using System;
using System.Collections.Generic;
using System.Text;

namespace SymAutomate.RawCommand
{
    /// <summary>
    /// Handles RawCommand functions
    /// Error Numbers 750-799; Reference file ErrorNumbers.txt for more information.
    /// 750 Error: Timed out waiting for text '%test%'.
    /// 701 Error: Required argument 'rawcommandparam' missing. Use /h switch for help.
    /// 702 Error: Argument 'rawcommandparam' invalid format. Use /h switch for help.
    /// </summary>
    class Driver : DriverBase, DriverInterface
    {
        private Parameters __Parameters;

        public Driver()
            : base()
        {
        }

        public Driver(ConsoleArguments _ConsoleArguments, HostTelnetConnection.Driver _HostTelnetConnectionDriver)
            : base(_HostTelnetConnectionDriver)
        {
            __Parameters = new Parameters(_ConsoleArguments, base.ConsoleHelpList);
        }

        /// <summary>
        /// Defines the command to function mapping;
        /// First parameter is what to expect as "command" from commmand line;
        /// Second parameter is the function name (case must match);
        /// </summary>
        public void PopulateCommandToFunctionMapping()
        {
            CommandToFunctionMapping.Add("RawCommand".ToLower(), "RawCommand");
        }

        /// <summary>
        /// Defines the help text for this driver
        /// </summary>
        public void PopulateConsoleHelp()
        {
            ConsoleHelp _ConsoleHelp = new ConsoleHelp("RawCommand");
            _ConsoleHelp.Parameters.Add("RawCommandType");
            _ConsoleHelp.Parameters.Add("RawCommandParam");
            ConsoleHelpList.Add(_ConsoleHelp);
        }

        public void RawCommand()
        {
            string s = "";

            try
            {
                if (__Parameters.RawCommandType == "aix")
                    HostTelnetConnectionDriver.AixLogin();
                else if (__Parameters.RawCommandType == "symop")
                    HostTelnetConnectionDriver.SymopLogin();
                else if (__Parameters.RawCommandType == "sym")
                    HostTelnetConnectionDriver.Login();

                bool _NextAsciiCommandReadFromBuffer = false;
                bool _IgnoreExpectedPromptFailure = false;

                for (int i = 0; i < __Parameters.RawCommandParameter.RawCommandParameterSegmentCollection.Count; i++)
                {
                    RawCommandParameter.RawCommandParameterSegment _RawCommandParameterSegment = __Parameters.RawCommandParameter.RawCommandParameterSegmentCollection[i];
                    if (_RawCommandParameterSegment.RawCommandParameterSegmentType == RawCommandParameter.RawCommandParameterSegmentType.Sleep)
                    {
                        System.Threading.Thread.Sleep(Convert.ToInt32(_RawCommandParameterSegment.Value));
                    }
                    else if (_RawCommandParameterSegment.RawCommandParameterSegmentType == RawCommandParameter.RawCommandParameterSegmentType.CommandIgnoreFailure)
                    {
                        if (_RawCommandParameterSegment.Value.ToString().ToLower() == "begin")
                            _IgnoreExpectedPromptFailure = true;
                        else if (_RawCommandParameterSegment.Value.ToString().ToLower() == "end")
                            _IgnoreExpectedPromptFailure = false;
                    }
                    else if (_RawCommandParameterSegment.RawCommandParameterSegmentType == RawCommandParameter.RawCommandParameterSegmentType.AsciiCommunication)
                    {
                        bool _ShouldSend = true;

                        try
                        {
                            if (_NextAsciiCommandReadFromBuffer == true)
                            {
                                _NextAsciiCommandReadFromBuffer = false;
                                if (!string.IsNullOrEmpty(_RawCommandParameterSegment.Prompt))
                                {                   
                                    if (!s.Contains(_RawCommandParameterSegment.Prompt))
                                        throw new System.Net.Sockets.SocketException(1);
                                }
                                else
                                {
                                    System.Threading.Thread.Sleep(200);
                                    HostTelnetConnectionDriver.LogIncommingStream(string.Empty);
                                }
                            }
                            else
                            {
                                if (!string.IsNullOrEmpty(_RawCommandParameterSegment.Prompt))
                                {
                                    s = HostTelnetConnectionDriver.TelnetWaitFor(_RawCommandParameterSegment.Prompt);
                                    HostTelnetConnectionDriver.LogIncommingStream(s);
                                }
                                else
                                {
                                    System.Threading.Thread.Sleep(200);
                                    HostTelnetConnectionDriver.LogIncommingStream(string.Empty);
                                }
                            }
                        }
                        catch (Dart.Telnet.DataException _DataException)
                        {
                            s = HostTelnetConnectionDriver.LogIncommingStream(_DataException.DataRead.ToString());

                            _ShouldSend = false;
                            if (_IgnoreExpectedPromptFailure)
                            {
                                _NextAsciiCommandReadFromBuffer = true;
                                //Console.WriteLine("** IGNORING ***");
                            }
                            else
                            {
                                throw new ReturnException("750 Error: Timed out waiting for text '" + _RawCommandParameterSegment.Prompt + "'." + Environment.NewLine + RawCommandParameter.GetFailedPromptLocation(__Parameters.RawCommandParameter.RawCommandParameterSegmentCollection, i));
                            }
                        }

                        if (_ShouldSend)
                        {
                            //TODO: here
                            HostTelnetConnectionDriver.TelnetSend(_RawCommandParameterSegment.Value + GlobalParameters.TelnetSendEndOfCommand);                                
                        }

                    }
                }

                System.Threading.Thread.Sleep(1000);
                HostTelnetConnectionDriver.LogIncommingStream(string.Empty);

            }
            catch (Exception e)
            {
                s = HostTelnetConnectionDriver.LogIncommingStream(string.Empty);
                HostTelnetConnectionDriver.HandleException(e, s);
            }
            finally
            {
                HostTelnetConnectionDriver.TelnetCloseConnection();
            }
        }
    }
}
